package com.wxy.demo.controller;

import cn.hutool.core.util.StrUtil;
import com.wxy.demo.core.IdDto;
import com.wxy.demo.core.PageResult;
import com.wxy.demo.core.QueryPage;
import com.wxy.demo.dao.UserInterfaceDao;
import com.wxy.demo.dto.InterfaceBindDto;
import com.wxy.demo.entity.InterfaceInfo;
import com.wxy.demo.entity.UserInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * </p>
 *
 * @author e-Xiaoyuan.Wang
 * @since 2022/4/12 13:54
 */
@Transactional
@RestController
@RequestMapping("user-interface")
public class UserInterfaceController {

    @Autowired
    private UserInterfaceDao userInterfaceDao;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @PostMapping("/findPage")
    private Object findPage(@RequestBody QueryPage<UserInterface> queryPage) {
        UserInterface query = Optional.ofNullable(queryPage.getQueryModel()).orElse(new UserInterface());
        String sql = "select ui.id,ii.name interface_name,di.name datasource_name,ii.status interface_status " +
                "from user_interface ui " +
                "left join interface_info ii on ii.id = ui.interface_id " +
                "left join data_source_info di on di.id = ii.data_source_id " +
                "where ui.user_id = ? " +
                "and ii.name like ? " +
                "and di.name like ? " +
                "order by ui.id asc " +
                "limit ?, ? ";
        String countSql = "select count(ui.id) from user_interface ui " +
                "left join interface_info ii on ii.id = ui.interface_id " +
                "left join data_source_info di on di.id = ii.data_source_id " +
                "where ui.user_id = ? " +
                "and ii.name like ? " +
                "and di.name like ? ";
        List<UserInterface> list = jdbcTemplate.queryForList(sql,
                        query.getUserId(),
                        "%" + Optional.ofNullable(query.getInterfaceName()).orElse("") + "%",
                        "%" + Optional.ofNullable(query.getDatasourceName()).orElse("") + "%",
                        (queryPage.getPageNum() - 1) * queryPage.getPageSize(), queryPage.getPageSize())
                .stream()
                .map(map -> new UserInterface((Long) map.get("id"), (String) map.get("interface_name"),
                        (String) map.get("datasource_name"), (Integer) map.get("interface_status")))
                .collect(Collectors.toList());
        long count = Optional.ofNullable(jdbcTemplate.queryForObject(countSql, Long.class,
                        query.getUserId(),
                        "%" + Optional.ofNullable(query.getInterfaceName()).orElse("") + "%",
                        "%" + Optional.ofNullable(query.getDatasourceName()).orElse("") + "%"
                ))
                .orElse(0L);
        return new PageResult<>(list, count / queryPage.getPageSize() + 1, count);
    }

    @PostMapping("/deleteById")
    private Object deleteById(@RequestBody IdDto dto) {
        userInterfaceDao.deleteById(dto.getId());
        return true;
    }

    @PostMapping("/bind")
    private Object bind(@RequestBody InterfaceBindDto dto) {
        StrUtil.split(dto.getInterfaceIds(), ",").forEach(id -> {
            Long interfaceId = Long.valueOf(id);
            UserInterface userInterface = userInterfaceDao.findByUserIdAndInterfaceId(dto.getUserId(), interfaceId);
            if (userInterface == null) {
                userInterfaceDao.save(new UserInterface(dto.getUserId(), interfaceId));
            }
        });
        return true;
    }

    @PostMapping("/findPageBind")
    private Object findPageBind(@RequestBody QueryPage<UserInterface> queryPage) {
        UserInterface query = Optional.ofNullable(queryPage.getQueryModel()).orElse(new UserInterface());
        String sql = "select ii.id,ii.name,di.name datasource_name " +
                "from interface_info ii " +
                "left join data_source_info di on di.id = ii.data_source_id " +
                "left join (select id,interface_id from user_interface where user_id = ?) ui on ui.interface_id = ii.id " +
                "where ii.status = 1 " +
                "and ii.is_share = 0 " +
                "and ui.id is null " +
                "and ii.name like ? " +
                "and di.name like ? " +
                "order by ii.id asc " +
                "limit ?, ? ";
        String countSql = "select count(ii.id) from interface_info ii " +
                "left join data_source_info di on di.id = ii.data_source_id " +
                "left join (select id,interface_id from user_interface where user_id = ?) ui on ui.interface_id = ii.id " +
                "where ii.status = 1 " +
                "and ii.is_share = 0 " +
                "and ui.id is null " +
                "and ii.name like ? " +
                "and di.name like ? ";
        List<InterfaceInfo> list = jdbcTemplate.queryForList(sql,
                        query.getUserId(),
                        "%" + Optional.ofNullable(query.getInterfaceName()).orElse("") + "%",
                        "%" + Optional.ofNullable(query.getDatasourceName()).orElse("") + "%",
                        (queryPage.getPageNum() - 1) * queryPage.getPageSize(), queryPage.getPageSize())
                .stream()
                .map(map -> new InterfaceInfo((Long) map.get("id"), (String) map.get("name"),
                        (String) map.get("datasource_name")))
                .collect(Collectors.toList());
        long count = Optional.ofNullable(jdbcTemplate.queryForObject(countSql, Long.class,
                        query.getUserId(),
                        "%" + Optional.ofNullable(query.getInterfaceName()).orElse("") + "%",
                        "%" + Optional.ofNullable(query.getDatasourceName()).orElse("") + "%"
                ))
                .orElse(0L);
        return new PageResult<>(list, count / queryPage.getPageSize() + 1, count);
    }
}
